/* ====================================================
#   Copyright (C)2019 Li Jianbin All rights reserved.
#
#   Author        : Li Jianbin
#   Email         : lijianbinmail@163.com
#   File Name     : c3dwidget.cpp
#   Last Modified : 2019-04-21 15:00
#   Describe      : 3D Widget
#
# ====================================================*/

#include "c3dwidget.h"
#include "makebottle.h"
#include "src/define/func_define.h"

//! 在0,0,0创建原点坐标系
static Handle_AIS_Trihedron createOriginTrihedron()
{
    gp_Ax2 axe2(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)); // 等价于gp::XOY()
    // gp_Ax2 axe2(gp_Pnt(0, 0, 0), gp_Dir(1, 0, 0), gp_Dir(0, 0, 1)); // 等价于gp::XOY()
    // gp::XOY()
    Handle_Geom_Axis2Placement axis = new Geom_Axis2Placement(axe2);
    Handle_AIS_Trihedron aisTrihedron = new AIS_Trihedron(axis);
    aisTrihedron->SetDatumDisplayMode(Prs3d_DM_WireFrame);  // 设置为细线
    aisTrihedron->SetDatumPartColor(Prs3d_DP_XArrow, Quantity_NOC_RED2);
    aisTrihedron->SetDatumPartColor(Prs3d_DP_YArrow, Quantity_NOC_GREEN2);
    aisTrihedron->SetDatumPartColor(Prs3d_DP_ZArrow, Quantity_NOC_BLUE2);
    aisTrihedron->SetDatumPartColor(Prs3d_DP_XAxis, Quantity_NOC_RED2);
    aisTrihedron->SetDatumPartColor(Prs3d_DP_YAxis, Quantity_NOC_GREEN2);
    aisTrihedron->SetDatumPartColor(Prs3d_DP_ZAxis, Quantity_NOC_BLUE2);
    aisTrihedron->SetLabel(Prs3d_DP_XAxis, "x");
    aisTrihedron->SetLabel(Prs3d_DP_YAxis, "y");
    aisTrihedron->SetLabel(Prs3d_DP_ZAxis, "z");
    aisTrihedron->SetDrawArrows(false);  // 不显示箭头
    //aisTrihedron->SetTextColor(Quantity_NOC_GRAY40);
    aisTrihedron->SetSize(0.4);
    aisTrihedron->SetInfiniteState(false);  //设置维无穷大
    return aisTrihedron;
}

C3DWidget::C3DWidget(QWidget *parent) : QGLWidget(parent)
  ,m_rubberBand(QRubberBand::Rectangle, parent)
{
    //配置QWidget
    setBackgroundRole( QPalette::NoRole );  //无背景
    setMouseTracking(true);             // 开启鼠标位置追踪
    installEventFilter(parent);         // 安装键盘事件
    setFocusPolicy(Qt::StrongFocus);    // 必须指定聚焦信息才能使用键盘事件
    connect(this,&C3DWidget::startAnimation,this,&C3DWidget::updateCurrentScense,Qt::DirectConnection);
    m_rubberBand.setStyle(QStyleFactory::create("windows"));
    ais_animation = new AIS_Animation("obj1");
    CreatAnimation();
}


void C3DWidget::SetModelLocation(const Handle(AIS_InteractiveObject)& aShape,gp_Trsf trsf,bool allowAnimation)
{
    if(allowAnimation){
        gp_Trsf start_pnt, end_pnt;
        start_pnt =  aShape->LocalTransformation();
        end_pnt = trsf;
        static int num =0;

        QString name = "obr" + QString::number(num);
        Handle(AIS_AnimationObject) ais_ao = new AIS_AnimationObject(name.toStdString().c_str(),
                                                                     m_context, aShape, start_pnt, end_pnt);
        ais_ao->SetOwnDuration(1);
        ais_ao->SetStartPts(0);
        ais_animation->Add(ais_ao);
        ais_animation->StartTimer(0, 1.0, true);
        num++;
        emit startAnimation();
    }else{
        m_context->SetLocation(aShape,trsf);
        // m_context->Update(aShape,Standard_True);  //等价于这句话 myContext->UpdateCurrentViewer();//窗口更新
    }

}

//! 设置一个对象的位置信息
//! arg1 视图模型对象
//! arg2 目标位置 3*4矩阵
//! arg3 是否以动画形式运动
void C3DWidget::setLocation(const Handle(AIS_InteractiveObject)& aShape, Pos3dzx pos,bool allowAnimation)
{
    //设置欧拉角
    gp_Trsf aTrsf_Rotation;
    gp_Quaternion aQ;
    aQ.SetEulerAngles(gp_Intrinsic_ZYZ,pos.a,pos.b,pos.c);
    aTrsf_Rotation.SetRotation(aQ);
    //设置平移向量
    gp_Trsf aTrsf_Translation;
    gp_Vec theVectorOfTrans(pos.x,pos.y,pos.z);
    aTrsf_Translation.SetTranslation(theVectorOfTrans);
    gp_Trsf trsf = aTrsf_Translation * aTrsf_Rotation;

    SetModelLocation(aShape,trsf,allowAnimation);
}

//! 对一个模型进行相对运动
void C3DWidget::relativeMove(const Handle(AIS_InteractiveObject)& aShape, Pos3dzx pos)
{
    qDebug()<<pos.x << pos.a;
    auto f = m_context->Location(aShape);

    gp_Trsf aTrsf_Rotation = aShape->LocalTransformation();

    double a = pos.a * M_PI / 180 ;
    double b = pos.b * M_PI / 180 ;
    double c = pos.c * M_PI / 180 ;

    gp_Trsf m;
    gp_Trsf rz1, ry, rz2,xyz;
    rz1.SetValues( cos(a), -sin(a), 0, 0,
                   sin(a),  cos(a), 0, 0,
                      0,   0, 1, 0);

    ry.SetValues( cos(b), 0, sin(b), 0,
                        0, 1,      0, 0,
                        -sin(b), 0, cos(b), 0);

    rz2.SetValues(cos(c), -sin(c), 0, 0,
          sin(c),  cos(c), 0, 0,
               0,       0, 1, 0);
    xyz.SetValues(1,0,0,pos.x,
                  0,1,0,pos.y,
                  0,0,1,pos.z);
    m = xyz*rz1*ry*rz2;
    auto real = m * aTrsf_Rotation;
    SetModelLocation(aShape,real);

}
void C3DWidget::make_cube(Standard_Real _dx, Standard_Real _dy, Standard_Real _dz)
{
    TopoDS_Shape t_topo_box = BRepPrimAPI_MakeBox(_dx, _dy, _dz).Shape();

    gp_Trsf theTransformation ;
    // theTransformation.SetMirror(gp_Pnt(2, 3 ,4));        // 点对称镜像
    // theTransformation.SetTranslation(gp_Vec(1, 1, 1));      // 平移
    // theTransformation.SetRotation (gp_Quaternion(2, 3 ,4,0));

    BRepBuilderAPI_Transform myBRepTransformation(t_topo_box,theTransformation, false);
    t_topo_box = myBRepTransformation.Shape();

    Handle(AIS_Shape) t_ais_box = new AIS_Shape(t_topo_box);
    m_context->Display(t_ais_box, Standard_True);
    //
    Pos3dzx pos = Pos3dzx::instance("20,20,20,4,5,6");
    setLocation(t_ais_box,pos);

    attachToPulator(t_ais_box);
    m_view->FitAll();
    auto ggg = createOriginTrihedron();
    m_context->Display(ggg, Standard_True);
    //setLocation(ggg,pos);
}

void C3DWidget::make_cylinder(Standard_Real _R, Standard_Real _H)
{
    TopoDS_Shape t_topo_cylinder = BRepPrimAPI_MakeCylinder(_R , _H).Shape();
    Handle(AIS_Shape) t_ais_cylinder = new AIS_Shape(t_topo_cylinder);
    m_context->Display(t_ais_cylinder, Standard_True);
    attachToPulator(t_ais_cylinder);
    m_view->FitAll();
}

void C3DWidget::make_sphere(Standard_Real _R)
{
    TopoDS_Shape t_topo_sphere = BRepPrimAPI_MakeSphere(_R).Shape();
    Handle(AIS_Shape) t_ais_sphere = new AIS_Shape(t_topo_sphere);
    m_context->Display(t_ais_sphere, Standard_True);
    attachToPulator(t_ais_sphere);
    m_view->FitAll();

}

void C3DWidget::make_cone(Standard_Real _R1, Standard_Real _R2, Standard_Real _H)
{
    TopoDS_Shape t_topo_cone = BRepPrimAPI_MakeCone(_R1,_R2,_H).Shape();
    Handle(AIS_Shape) t_ais_cone = new AIS_Shape(t_topo_cone);

    Handle(Graphic3d_AspectFillArea3d) aFaceAspect = new Graphic3d_AspectFillArea3d();

    Graphic3d_MaterialAspect aGoldMaterial (Graphic3d_NOM_GLASS);
    aFaceAspect->SetInteriorStyle (Aspect_IS_SOLID);
    aFaceAspect->SetInteriorColor (Quantity_NOC_LIGHTBLUE4);
    aFaceAspect->SetDistinguishOn ();
    aFaceAspect->SetFrontMaterial (aGoldMaterial);
    aFaceAspect->SetEdgeOn();
    Graphic3d_MaterialAspect aBrassMaterial (Graphic3d_NOM_BRASS);

    m_context->SetMaterial(t_ais_cone,aBrassMaterial, Standard_True);
    m_context->Display(t_ais_cone, Standard_True);
    m_view->FitAll();
    attachToPulator(t_ais_cone);
}

void C3DWidget::make_torus(Standard_Real _R1, Standard_Real _R2)
{
    TopoDS_Shape t_topo_torus = BRepPrimAPI_MakeTorus(_R1 ,_R2).Shape();
    Handle(AIS_Shape) t_ais_torus = new AIS_Shape(t_topo_torus);
    m_context->Display(t_ais_torus, Standard_True);
    m_view->FitAll();
}

void C3DWidget::setDefaultMouse(int mod)
{
    default_mode = CurrentAction3d(mod);
}


/*
    * 将对象模型绑定到坐标系旋转
*/
void C3DWidget::bindCoordinate(const Handle(AIS_InteractiveObject)& aShape)
{
    aViewCube = Handle(AIS_ViewCube)::DownCast(aShape);
    if (aViewCube.IsNull()) {
        aViewCube = new AIS_ViewCube();
        aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
        m_context->Display(aViewCube, Standard_True);
    }
}

/**
 * @brief CMainWindow::showSomePath
 * @details 显示一串轨迹-----点云方式
 */
void C3DWidget::showSomePath(std::vector<Pos3dzx> f)
{
    Handle(Graphic3d_ArrayOfPoints) aPtsArr = new Graphic3d_ArrayOfPoints (f.size(), 2);
    for(auto p:f){
        aPtsArr->AddVertex (gp_Pnt (p.x, p.y, p.z), Quantity_Color(Quantity_NOC_LIGHTBLUE4));
    }
    Handle(AIS_PointCloud) aPntCloud = new AIS_PointCloud();
    aPntCloud->SetColor(Quantity_NOC_LIGHTBLUE4);
    aPntCloud->SetDisplayMode(0);
    aPntCloud->SetHilightMode(100);
    aPntCloud->SetPoints(aPtsArr);
    m_context->Display(aPntCloud,Standard_True);
    m_view->FitAll();

}

/**
 * @brief CMainWindow::showSomePath
 * @details 显示一串轨迹-----多边形方式
 */
void C3DWidget::showPolygonPath(std::vector<Pos3dzx> f)
{
    Handle(AIS_Shape) SHAPE = new AIS_Shape(make_PolygonPath(f));
    SHAPE->SetColor(Quantity_NOC_PINK);
    SHAPE->SetWidth(5);
    m_context->Display(SHAPE,Standard_True);
    bindCoordinate(SHAPE);
    m_view->FitAll();
}

/**
 * @brief CMainWindow::showSomePath
 * @details 显示一串轨迹-----多边形方式
 */
void C3DWidget::showAxles(std::vector<Pos3dzx> f)
{
    showPolygonPath(f);
    for(auto p:f){
        auto ggg = createOriginTrihedron();
        m_context->Display(ggg, false);
        setLocation(ggg,p);
    }
    m_view->FitAll();
}

//! 设置相机1的位置
void C3DWidget::setCameraPosition(Pos3dzx f)
{
    scaneCam->SetEye(gp_Pnt(f.x,f.y,f.z));
    m_context->UpdateCurrentViewer();
}

//! 设置相机1的相对运动位置
void C3DWidget::setCameraRelativePosition(gp_Pnt f)
{
    auto  pos = scaneCam->Eye();
    pos.SetX(pos.X() + f.X());
    pos.SetY(pos.Y() + f.Y());
    pos.SetZ(pos.Z() + f.Z());
    scaneCam->SetEye(pos);

    m_context->UpdateCurrentViewer();
}

void C3DWidget::setRelateParament(ControlIndex index, int val)
{
    switch (index) {
    case TP_ZOOM:
        m_view->SetZoom(val);   // 放大
        break;
    case TP_X_STEP:

        break;
    case TP_Y_STEP:
        break;
    case TP_CAM_CHANGED:
        val == 0  ? m_view->SetCamera(m_view->DefaultCamera()) : m_view->SetCamera(scaneCam);
        m_context->UpdateCurrentViewer();
        break;
    case TP_GRID:
        0 < val ? m_viewer->ActivateGrid(Aspect_GT_Rectangular,Aspect_GDM_Lines)
                 :m_viewer->DeactivateGrid();
        m_context->UpdateCurrentViewer();
        break;
    case TP_CAMX:
        setCameraRelativePosition(gp_Pnt(val,0,0));
        break;
    case TP_CAMY:
        setCameraRelativePosition(gp_Pnt(0,val,0));
        break;
    case TP_CAMZ:
        setCameraRelativePosition(gp_Pnt(0,0,val));
        break;

    case TP_CAMS:
        scaneCam->SetScale(val/100.0);
        m_context->UpdateCurrentViewer();
        break;
    }
}

//! 生成动画同步模型运动
void C3DWidget::genAnimations(std::vector<Pos3dzx> f)
{
    TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(gp_Pnt(0.0, 0.0, 0.0));
    TopoDS_Shape aPrismVertex = BRepPrimAPI_MakePrism(aVertex, gp_Vec(-10.0, -10.0, -10.0));
    Handle(AIS_Shape) obj = new AIS_Shape(aPrismVertex);
    obj->SetColor(Quantity_NOC_DARKGREEN);
    obj->SetWidth(10);
    m_context->Display(obj, Standard_True);
    // m_view->FitAll(obj->BoundingBox());
    showPolygonPath(f);
    // scaneCam->SetScale(0.008);
    // scaneCam->SetDistance(-16);
    for(auto p:f){
        // scaneCam->SetCenter(gp_Pnt(p.x,p.y,p.z));
        setLocation(obj,p,true);
    }

}

void C3DWidget::m_initialize_context()
{
    //若交互式上下文为空，则创建对象
    if (m_context.IsNull())
    {
        //此对象提供与X server的连接，在Windows和Mac OS中不起作用
        Handle(Aspect_DisplayConnection) m_display_donnection = new Aspect_DisplayConnection();
        //创建OpenGl图形驱动
        if (m_graphic_driver.IsNull())
        {
            m_graphic_driver = new OpenGl_GraphicDriver(m_display_donnection);
        }
        //获取QWidget的窗口系统标识符
        WId window_handle = (WId) winId();
#ifdef _WIN32
        // 创建Windows NT 窗口
        Handle(WNT_Window) wind = new WNT_Window((Aspect_Handle) window_handle);
#else
        // 创建XLib window 窗口
        Handle(Xw_Window) wind = new Xw_Window(m_display_donnection, (Window) window_handle);
#endif
        //创建3D查看器
        m_viewer = new V3d_Viewer(m_graphic_driver);
        //创建视图
        m_view = m_viewer->CreateView();
        m_view->SetWindow(wind);
        //打开窗口
        if (!wind->IsMapped())
        {
            wind->Map();
        }
        m_context = new AIS_InteractiveContext(m_viewer);  //创建交互式上下文
        //配置查看器的光照
        m_viewer->SetDefaultLights();		//设置默认光源
        Handle(V3d_AmbientLight) aLight1 = new V3d_AmbientLight( Quantity_NOC_GRAY50);	// 环境光
        aLight1->SetIntensity(0.4);//　光线强度
        m_viewer->AddLight(aLight1);
        m_viewer->SetLightOn();
        //设置视图的背景颜色为纯黑色
        //m_view->SetBackgroundColor(Quantity_NOC_BLACK);
        m_view->SetBgGradientColors(Quantity_NOC_SKYBLUE,Quantity_NOC_WHEAT3);
        m_view->MustBeResized();
        //显示直角坐标系，可以配置在窗口显示位置、文字颜色、大小、样式
        aViewCube = new AIS_ViewCube();
        aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
        m_context->Display(aViewCube, Standard_True);
        // m_view->TriedronDisplay(Aspect_TOTP_LEFT_LOWER, Quantity_NOC_GOLD, 0.1, V3d_ZBUFFER);

        //设置显示模式
        m_context->SetDisplayMode(AIS_Shaded, Standard_True);
        scaneCam = new  Graphic3d_Camera();
        scaneCam->SetEye(gp_Pnt(0,0,0));

        // 设置模型高亮的风格        Quantity_NOC_LIGHTSTEELBLUE1
        Handle(Prs3d_Drawer) t_hilight_style = m_context->HighlightStyle(); // 获取高亮风格
        t_hilight_style->SetMethod(Aspect_TOHM_BOUNDBOX);  // 颜色显示方式
        t_hilight_style->SetColor(Quantity_NOC_LIGHTGRAY);    // 设置高亮颜色
        t_hilight_style->SetDisplayMode(1); // 整体高亮
        t_hilight_style->SetTransparency(0.2f); // 设置透明度

        // 设置选择模型的风格
        Handle(Prs3d_Drawer) t_select_style = m_context->SelectionStyle();  // 获取选择风格
        t_select_style->SetMethod(Aspect_TOHM_COLOR);  // 颜色显示方式
        t_select_style->SetColor(Quantity_NOC_LIGHTSTEELBLUE);   // 设置选择后颜色
        t_select_style->SetDisplayMode(1); // 整体高亮
        t_select_style->SetTransparency(0.1f); // 设置透明度

        // m_view->SetZoom(100);   // 放大

        // 激活二维网格
        m_viewer->SetRectangularGridValues(0,0,100,100,0);
        m_viewer->SetRectangularGridGraphicValues(2000,2000,0);
        m_viewer->ActivateGrid(Aspect_GT_Rectangular,Aspect_GDM_Lines);
    }
}


void  C3DWidget::updateCurrentScense()
{
    while (!ais_animation->IsStopped())
    {
        ais_animation->UpdateTimer();

        m_context->UpdateCurrentViewer();
    }
}

void C3DWidget::paintEvent(QPaintEvent *)
{
    if(aManipulator.IsNull()){  // 若未定义模型操作器
        aManipulator = new AIS_Manipulator;
        // aManipulator->EnableMode (AIS_ManipulatorMode::AIS_MM_Translation);
        aManipulator->EnableMode (AIS_ManipulatorMode::AIS_MM_Rotation);
        // aManipulator->EnableMode (AIS_ManipulatorMode::AIS_MM_Scaling);
        aManipulator->SetModeActivationOnDetection(Standard_True);

    }
    if (m_context.IsNull()) // 若未定义交互环境
    {
        m_initialize_context(); // 初始化交互环境
        m_context->MainSelector()->SetPickClosest(Standard_False);     // 确保z层被捕获到
    }

    m_view->Redraw();
}

void C3DWidget::resizeEvent(QResizeEvent *)
{
    if( !m_view.IsNull() ) {
        m_view->MustBeResized();
    }
}

void C3DWidget::mousePressEvent(QMouseEvent *event)
{
    QPoint currPos = mapFromGlobal(event->globalPos());
    currPos += this->pos();
    startPos = currPos;
    if(event->buttons()&Qt::LeftButton){
        if(event->buttons()&Qt::RightButton || qApp->keyboardModifiers()==Qt::ShiftModifier || isMPressed){
            m_current_mode = CurAction3d_DynamicPanning;
        }else if (qApp->keyboardModifiers()==Qt::ControlModifier) {
            m_current_mode = CurAction3d_Selecte;
        }
        else {
            // 点击前，将鼠标位置传递到交互环境
            m_context->MoveTo(event->pos().x(),event->pos().y(),m_view,Standard_True);
            m_current_mode = isVPressed ?  SelectAction3d_Pann: default_mode;
            switch (default_mode) {
                case CurAction3d_DynamicZooming:
                this->setCursor(Qt::SizeBDiagCursor);
                drawRubbing = true;
                break;
            }


        }

    }
    else if(event->buttons()&Qt::RightButton || event->buttons()&Qt::MidButton){
        m_current_mode = CurAction3d_DynamicRotation;
    }else{
        m_current_mode = CurAction3d_Nothing;
    }


    switch (m_current_mode) {
        case CurAction3d_DynamicPanning:
            // 初始化平移
            m_x_max=event->x();
            m_y_max=event->y();
            this->setCursor(Qt::SizeAllCursor);
            break;
        case CurAction3d_DynamicZooming:
            break;

        case CurAction3d_Nothing:

            break;
        case CurAction3d_DynamicRotation:
            m_x_max=event->x();
            m_y_max=event->y();
            this->setCursor(Weldroid::rotateCursor());
            // 初始化旋转
            m_view->StartRotation(event->x(),event->y());
            break;
        case CurAction3d_Selecte:
            setMuliModel(qApp->keyboardModifiers()==Qt::ControlModifier);
            break;     
        case  SelectAction3d_Pann:
            if (aManipulator->HasActiveMode()){
              aManipulator->StartTransform (event->pos().x(), event->pos().y(), m_view);
            }
            break;
    }



}

void C3DWidget::mouseReleaseEvent(QMouseEvent *event)
{
    // 将鼠标位置传递到交互环境
    m_context->MoveTo(event->pos().x(),event->pos().y(),m_view,Standard_True);
    switch (m_current_mode) {
        case CurAction3d_DynamicZooming:
            QPoint currPos = this->mapFromGlobal(event->globalPos());
            currPos += this->pos();
            windowFit(startPos,currPos);
            m_rubberBand.setVisible(false);
            drawRubbing = false;
        break;
    }
    this->setCursor(Qt::ArrowCursor);
    m_current_mode = CurAction3d_Nothing;
}

void C3DWidget::mouseMoveEvent(QMouseEvent *event)
{
    updatePos(event);   // ui界面显示pos信息更新
    switch (m_current_mode) {
        case CurAction3d_DynamicPanning:
            m_view->Pan(event->pos().x()-m_x_max,m_y_max-event->pos().y());
            m_x_max=event->x();
            m_y_max=event->y();
            break;
        case CurAction3d_Nothing:
            // 将鼠标位置传递到交互环境
            // m_context->MoveTo(event->pos().x(),event->pos().y(),m_view,Standard_True);
            break;
        case CurAction3d_DynamicRotation:
            m_view->Rotation(event->x(),event->y());
            break;
        case CurAction3d_Selecte:
            break;
        case  SelectAction3d_Pann:
            if (aManipulator->HasActiveMode()){
              aManipulator->Transform (event->pos().x(), event->pos().y(), m_view);
              m_view->Redraw();
            }
            break;
    case CurAction3d_DynamicZooming:
        QPoint currPos = this->mapFromGlobal(event->globalPos());
        currPos += this->pos();
        drawRubberBand(startPos,currPos);
        break;
    }


    // or track mouse move event


}

void C3DWidget::wheelEvent(QWheelEvent *event)
{
    m_view->StartZoomAtPoint(event->pos().x(),event->pos().y());
    m_view->ZoomAtPoint(0, 0, event->angleDelta().y(), 0); //执行缩放
}

void C3DWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
    if(!(event->button()&Qt::LeftButton)) return;
    t_pick_status = m_context->Select(true);        // 单选
    if(CurAction3d_DynamicPanning == default_mode){
        attachToPulator(m_context->FirstSelectedObject());
    }
    bindCoordinate(m_context->SelectedInteractive());
}

void C3DWidget::keyPressEvent(QKeyEvent *e)
{
    switch (e->key()) {
    case Qt::Key_Delete:
        try {
            OCC_CATCH_SIGNALS;
            m_context->Remove(m_context->SelectedInteractive(),true);
        } catch (Standard_Failure e) {
            qDebug()<<e.GetMessageString();
        }
    break;
    case Qt::Key_Escape:
        m_context->ClearSelected(true);     // 清除选取内的模型
    break;
    case Qt::Key_F4:
        qDebug()<<("Key_F4\n");
        if(m_context->SelectedInteractive().IsNull()){
            Handle(AIS_InteractiveObject) a= m_context->SelectedInteractive();
            attachToPulator(a);
        }else{
            attachToPulator(m_context->SelectedInteractive());
        }

    break;
    case Qt::Key_Left:
        qDebug()<<("Key_Left\n");
    break;
    case Qt::Key_Space:
        m_context->ClearSelected(true);
         attachToPulator(m_context->SelectedInteractive());
         // aManipulator->SetDisplayMode(-1);
    break;
    case Qt::Key_V:
        isVPressed = true;
        break;
    case Qt::Key_M:
        isMPressed = true;
        break;
    }
}

void C3DWidget::keyReleaseEvent(QKeyEvent *e)
{
    switch (e->key()) {
    case  Qt::Key_Delete:
        if(m_context->NbSelected() != 0){   // 如果有选择到模型

        }
        m_context->EraseSelected(true);
        m_context->RemoveAll(true);
        break;
    case Qt::Key_V:
        isVPressed = false;
        break;
    case Qt::Key_M:
        isMPressed = false;
        break;
    }
}


//　检测碰撞
bool C3DWidget::IsCommon()
{

}

void C3DWidget::getDescs()
{

}


// 设置模型选择模式
void C3DWidget::setMuliModel(bool value)
{
    t_pick_status = value ? m_context->ShiftSelect(true):t_pick_status = m_context->Select(true);
}

//! 提交鼠标位置的变更信息
void C3DWidget::updatePos(QMouseEvent *event)
{
    Standard_Real X,Y,Z;
    m_view->Convert(int(event->pos().x()),int(event->pos().y()),X,Y,Z);
    Pos3dzx f=Pos3dzx::instance();
    f.x = X;
    f.y = Y;
    f.z = Z;
    emit showPosition(f);       // 提交坐标显示
}

//! 绘制缩放板
void C3DWidget::drawRubberBand(QPoint start, QPoint end)
{
    QRect rect;
    rect.setX(std::min(start.x(), end.x()));
    rect.setY(std::min(start.y(), end.y()));
    rect.setWidth(std::abs(end.x() - start.x()));
    rect.setHeight(std::abs(end.y() - start.y()));
    m_rubberBand.setGeometry(rect);
    m_rubberBand.setVisible(true);
}

//! 场景自适应
void C3DWidget::windowFit(QPoint posMin, QPoint posMax)
{
    if (std::abs(posMin.x() - posMax.x()) > 1 || std::abs(posMin.y() - posMax.y()) > 1)
        m_view->WindowFitAll(posMin.x()-this->x(), posMin.y()-this->y(),
                             posMax.x()-this->x(), posMax.y()-this->y());
}

void C3DWidget::CreatAnimation()
{
//    std::thread([this](const Handle(V3d_View)& m_view1){
//        while (1) {
//            while (isMoving.load()) {
//                ais_animation->StartTimer(0, 1.0, true);
//                isMoving.store(false);
//            }

//            while (!ais_animation->IsStopped()){
//                ais_animation->UpdateTimer();
//                 m_view1->ZFitAll();
////                m_view1->SetImmediateUpdate(true);
//                 m_view1->Update();
//            }
//            sleep_ms(10);
//        }
//    },m_view).detach();
}


/*
    ** 绑定控制器到模型中
*/
void C3DWidget::attachToPulator(const Handle(AIS_InteractiveObject)& aobj)
{
    Handle(AIS_Manipulator) aNew = new AIS_Manipulator;
    if(aobj.IsNull()){
        if(aManipulator->IsAttached()){
            aManipulator->DeactivateCurrentMode();  // 释放上次的控制器
            aManipulator->Detach();                 // 释放上次指针
        }
        return;
    }
    try {
        OCC_CATCH_SIGNALS
        aNew->Attach(aobj);
    } catch (Standard_Failure e) {
        qDebug()<<e.GetMessageString();
    }catch(...){
        qDebug()<<"其他异常";
    }
    aNew->EnableMode (AIS_ManipulatorMode::AIS_MM_Rotation);
    aNew->SetModeActivationOnDetection(Standard_True);
    if(aManipulator->IsAttached()){
        aManipulator->DeactivateCurrentMode();  // 释放上次的控制器
        aManipulator->Detach();                 // 释放上次指针
    }
    aManipulator = aNew;
}
